home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Source.bin / DirectionButton.java < prev    next >
Text File  |  1998-10-15  |  25KB  |  777 lines

  1. package symantec.itools.awt;
  2.  
  3. import java.awt.Rectangle;
  4. import java.awt.Dimension;
  5. import java.awt.Color;
  6. import java.awt.Graphics;
  7. import java.awt.SystemColor;
  8. import java.beans.PropertyVetoException;
  9. import java.beans.PropertyChangeListener;
  10. import java.beans.VetoableChangeListener;
  11. import java.beans.PropertyChangeEvent;
  12. import java.lang.IllegalArgumentException;
  13. import symantec.itools.awt.util.ColorUtils;
  14. import java.util.ResourceBundle;
  15.  
  16. //    01/29/97    TWB    Integrated changes from Windows
  17. //    05/23/97    LAB    Updated to support Java 1.1
  18. //    06/27/97    LAB    Changed the way the button is drawn.  Now it uses the offscreen
  19. //                    Image.  Cleaned up the drawing code to be more universal.
  20. //                    Added the ArrowColor property to allow the arrow to have a
  21. //                    user definable color.  The disabled color is derived from this color.
  22. //    07/02/97    LAB    Constrained the Arrow Indent Property, so the arrow wouldn't draw strangely
  23. //                    if the inset was set to a large value.
  24. //    07/08/97    LAB    Changed the preferedSize() method to return a button whose arrow is 20 by 20.
  25. //    07/13/97    RKM    Fixed misspelling of prefered
  26. //    07/19/97    LAB    Replaced updatePolygon with fillTriangle and changed the drawing method from
  27. //                    using a polygon to using lines because polygons were problematic.  Changed
  28. //                    getPreferredSize to return the smallest size which the button looks good and
  29. //                    changed getMinimumSize to return the smallest possible size for the button and
  30. //                    still be recognized as a DirectionButton.
  31. //  07/25/97    CAR marked fields transient as needed
  32. //                  innerclasses implement java.io.Serializable
  33. //    10/05/97    LAB    Changed names of strings in PropertyChangeEvent handling to follow Bean Spec
  34. //                    naming conventions.  Added mechanism for internally constrained properties
  35. //                    to be validated after the component is added to the form to avoid code-gen
  36. //                    order specific dependencies.
  37. //    10/06/97    LAB    Initialized tempIndent to indent which resolves shrinkTriangle
  38. //                    and setArrowIndent conflicts (Addresses Mac Bug #9014).  Changed
  39. //                    addNotify to call it's super after listeners are hooked up so
  40. //                    verifyContstrainedPropertyValues will be called after the listeners
  41. //                    are hooked up.  Changed setArrowIndent to set the temp value to the
  42. //                    current value when changing the current value.  Changed
  43. //                    getBevelHeight to return the temp value if the component is not
  44. //                    added.  This fixes a problem at design time where the component would
  45. //                    revert to it's default state after a back run
  46.  
  47. /**
  48.  * The DirectionButton is a button component that has an arrow drawn in it that
  49.  * points one of four ways (left, up, right, or down). At runtime, the button has
  50.  * a raised look and a pressed look.
  51.  * <p>
  52.  * This component is usually used in conjunction with a combo or list box to
  53.  * indicate a list that the user can view by clicking the arrow, or with spinners
  54.  * to let the user scroll through available values.
  55.  * <p>
  56.  * @version 1.1, June 27, 1997
  57.  * @author  Symantec
  58.  */
  59. public class DirectionButton extends ButtonBase implements java.io.Serializable
  60. {
  61.     /**
  62.      * The point LEFT style constant.
  63.      */
  64.     public static final int LEFT = 0;
  65.  
  66.     /**
  67.      * The point RIGHT style constant.
  68.      */
  69.     public static final int RIGHT = 1;
  70.  
  71.     /**
  72.      * The point UP style constant.
  73.      */
  74.     public static final int UP = 2;
  75.  
  76.     /**
  77.      * The point DOWN style constant.
  78.      */
  79.     public static final int DOWN = 3;
  80.  
  81.     /**
  82.      * Constructs a default DirectionButton, which will point left.
  83.      */
  84.     public DirectionButton()
  85.     {
  86.         this(LEFT);
  87.     }
  88.  
  89.     /**
  90.      * Constructs a DirectionButton pointing the specified direction.
  91.      * @param d a style constant indicating which direction to point the button
  92.      * @see #LEFT
  93.      * @see #UP
  94.      * @see #RIGHT
  95.      * @see #DOWN
  96.      */
  97.     public DirectionButton(int d)
  98.     {
  99.         direction     = d;
  100.         left         = 0;
  101.         right        = 0;
  102.         bottom        = 0;
  103.         indent        = 0;
  104.         tempIndent    = indent;
  105.         try {
  106.             setArrowColor(SystemColor.controlText);
  107.         } catch (PropertyVetoException exc) {}
  108.  
  109.     }
  110.  
  111.     /**
  112.      * Sets the direction of the arrow after construction.
  113.      * @param d constant indicating direction to point button
  114.      * @exception PropertyVetoException
  115.      * if the specified property value is unacceptable
  116.      * @see #getDirection
  117.      * @see #LEFT
  118.      * @see #UP
  119.      * @see #RIGHT
  120.      * @see #DOWN
  121.      */
  122.     public void setDirection(int d) throws PropertyVetoException
  123.     {
  124.         if(direction != d)
  125.         {
  126.             Integer oldValue = new Integer(direction);
  127.             Integer newValue = new Integer(d);
  128.  
  129.             vetos.fireVetoableChange("direction", oldValue, newValue);
  130.  
  131.             direction = d;
  132.             repaint();
  133.  
  134.             changes.firePropertyChange("direction", oldValue, newValue);
  135.         }
  136.     }
  137.  
  138.     /**
  139.      * Returns the direction the button is currently pointing.
  140.      * @see #setDirection
  141.      * @see #LEFT
  142.      * @see #UP
  143.      * @see #RIGHT
  144.      * @see #DOWN
  145.      */
  146.     public int getDirection()
  147.     {
  148.         return direction;
  149.     }
  150.  
  151.     /**
  152.      * Sets the amount of blank space between the arrow and the button
  153.      * border in pixels.
  154.      * @param ai the margin around the arrow in pixels. 0=arrow takes up entire button
  155.      * @exception PropertyVetoException
  156.      * if the specified property value is unacceptable
  157.      * @see #getArrowIndent
  158.      */
  159.     public void setArrowIndent(int ai) throws PropertyVetoException
  160.     {
  161.         if(isAdded)
  162.         {
  163.             if(indent != ai)
  164.             {
  165.                 Integer oldValue = new Integer(indent);
  166.                 Integer newValue = new Integer(ai);
  167.  
  168.                 vetos.fireVetoableChange("arrowIndent", oldValue, newValue);
  169.  
  170.                 indent = ai;
  171.                 tempIndent = ai;
  172.                 //Make sure that changes to indent don't make changes to shrinkTriangle
  173.                 //give us a bad triangle.
  174.                 shrinkTriangle(left, right, top, bottom);
  175.                 repaint();
  176.  
  177.                 changes.firePropertyChange("arrowIndent", oldValue, newValue);
  178.             }
  179.         }
  180.         //We store the value until we are added then set the value to avoid code-gen order dependencies.
  181.         else
  182.         {
  183.             tempIndent = ai;
  184.         }
  185.     }
  186.  
  187.     /**
  188.      * Sets the color of the direction arrow.
  189.      * @param newValue the new arrow color.
  190.      * @exception PropertyVetoException
  191.      * if the specified property value is unacceptable
  192.      * @see #getArrowColor
  193.      */
  194.     public void setArrowColor(Color newValue) throws PropertyVetoException
  195.     {
  196.         if (!symantec.itools.util.GeneralUtils.objectsEqual(arrowColor, newValue))
  197.         {
  198.             Color oldValue = arrowColor;
  199.  
  200.             vetos.fireVetoableChange("arrowColor", oldValue, newValue);
  201.  
  202.             arrowColor = newValue;
  203.             try
  204.             {
  205.                 disabledArrowColor = ColorUtils.fade(arrowColor, Color.lightGray, 0.50);
  206.             }
  207.             catch (IllegalArgumentException exc) {}
  208.  
  209.             repaint();
  210.  
  211.             changes.firePropertyChange("arrowColor", oldValue, newValue);
  212.         }
  213.     }
  214.  
  215.     /**
  216.      * Gets the current color of the direction arrow.
  217.      * @return the current arrow color
  218.      * @see #setArrowColor
  219.      */
  220.     public Color getArrowColor()
  221.     {
  222.         return arrowColor;
  223.     }
  224.  
  225.     /**
  226.      * Returns the amount of blank space between the arrow and the button
  227.      * border in pixels.
  228.      * @see #setArrowIndent
  229.      */
  230.     public int getArrowIndent()
  231.     {
  232.         return isAdded ? indent : tempIndent;
  233.     }
  234.  
  235.     /**
  236.      * Sets the extra amount, in pixels, to shrink the arrow triangle.
  237.      * Constrains the values such that the arrow will never be less than
  238.      * three pixels.  If a value is entered that would exceed this limit,
  239.      * the limit will be used instead.
  240.      * @param left pixels to shrink from left side
  241.      * @param right pixels to shrink from right side
  242.      * @param top pixels to shrink from top
  243.      * @param bottom pixels to shrink from bottom
  244.      */
  245.     public void shrinkTriangle(int l, int r, int t, int b)
  246.     {
  247.         if(isAdded)
  248.         {
  249.             Dimension s = getSize();
  250.             int maxWidth    = s.width - bevel - bevel - 2;
  251.             int maxHeight    = s.height - bevel - bevel - 2;
  252.  
  253.             if(maxWidth - (l + r + indent + indent) >= 3)
  254.             {
  255.                 left    = l;
  256.                 right    = r;
  257.             }
  258.             else
  259.             {
  260.                 left    = (maxWidth - indent - indent - 3) / 2;
  261.                 right    = left;
  262.             }
  263.  
  264.             if(maxHeight - (t + b + indent + indent) >= 3)
  265.             {
  266.                 top        = t;
  267.                 bottom    = b;
  268.             }
  269.             else
  270.             {
  271.                 top    = (maxHeight - indent - indent - 3) / 2;
  272.                 bottom    = top;
  273.             }
  274.         }
  275.     }
  276.  
  277.     /**
  278.      * Returns the recommended dimensions to properly display this component.
  279.      * This is a standard Java AWT method which gets called to determine
  280.      * the recommended size of this component.
  281.      *
  282.      * @return a button that has a content area of 7 by 7 pixels.
  283.      * @see java.awt.Component#getMinimumSize
  284.      */
  285.     public Dimension getPreferredSize()
  286.     {
  287.         Dimension defaultSize = super.getPreferredSize();
  288.  
  289.         return new Dimension(defaultSize.width + 7, defaultSize.height + 7);
  290.     }
  291.  
  292.     /**
  293.      * Returns the minimum dimensions to properly display this component.
  294.      * This is a standard Java AWT method which gets called to determine
  295.      * the minimum size of this component.
  296.      *
  297.      * @return a button that has a content area of 3 by 3 pixels.
  298.      * @see java.awt.Component#getMinimumSize
  299.      */
  300.     public Dimension getMinimumSize()
  301.     {
  302.         Dimension defaultSize = super.getPreferredSize();
  303.  
  304.         return new Dimension(defaultSize.width + 3, defaultSize.height + 3);
  305.     }
  306.  
  307.     /**
  308.      * Tells this component that it has been added to a container.
  309.      * This is a standard Java AWT method which gets called by the AWT when
  310.      * this component is added to a container. Typically, it is used to
  311.      * create this component's peer.
  312.      *
  313.      * It has been overridden here to hook-up event listeners.
  314.      *
  315.      * @see #removeNotify
  316.      */
  317.     public synchronized void addNotify()
  318.     {
  319.         errors = ResourceBundle.getBundle("symantec.itools.resources.ErrorsBundle");
  320.  
  321.         //Hook up listeners
  322.         if (sizeVeto == null)
  323.         {
  324.             sizeVeto = new SizeVeto();
  325.             addDirectionListener(sizeVeto);
  326.         }
  327.         if (indentVeto == null)
  328.         {
  329.             indentVeto = new IndntVeto();
  330.             addArrowIndentListener(indentVeto);
  331.         }
  332.  
  333.         //Add after the listeners are hooked up
  334.         super.addNotify();
  335.     }
  336.  
  337.     /**
  338.      * Tells this component that it is being removed from a container.
  339.      * This is a standard Java AWT method which gets called by the AWT when
  340.      * this component is removed from a container. Typically, it is used to
  341.      * destroy the peers of this component and all its subcomponents.
  342.      *
  343.      * It has been overridden here to unhook event listeners.
  344.      *
  345.      * @see #addNotify
  346.      */
  347.     public synchronized void removeNotify()
  348.     {
  349.         //Unhook listeners
  350.         if (sizeVeto != null)
  351.         {
  352.             removeDirectionListener(sizeVeto);
  353.             sizeVeto = null;
  354.         }
  355.         if (indentVeto != null)
  356.         {
  357.             removeArrowIndentListener(indentVeto);
  358.             indentVeto = null;
  359.         }
  360.  
  361.         super.removeNotify();
  362.     }
  363.  
  364.     /**
  365.      * Adds a listener for all event changes.
  366.      * @param listener the listener to add.
  367.      * @see #removePropertyChangeListener
  368.      */
  369.     public synchronized void addPropertyChangeListener(PropertyChangeListener listener)
  370.     {
  371.         super.addPropertyChangeListener(listener);
  372.         changes.addPropertyChangeListener(listener);
  373.     }
  374.  
  375.     /**
  376.      * Removes a listener for all event changes.
  377.      * @param listener the listener to remove.
  378.      * @see #addPropertyChangeListener
  379.      */
  380.     public synchronized void removePropertyChangeListener(PropertyChangeListener listener)
  381.     {
  382.         super.removePropertyChangeListener(listener);
  383.         changes.removePropertyChangeListener(listener);
  384.     }
  385.  
  386.     /**
  387.      * Adds a vetoable listener for all event changes.
  388.      * @param listener the listener to add.
  389.      * @see #removeVetoableChangeListener
  390.      */
  391.     public synchronized void addVetoableChangeListener(VetoableChangeListener listener)
  392.     {
  393.          super.addVetoableChangeListener(listener);
  394.         vetos.addVetoableChangeListener(listener);
  395.     }
  396.  
  397.     /**
  398.      * Removes a vetoable listener for all event changes.
  399.      * @param listener the listener to remove.
  400.      * @see #addVetoableChangeListener
  401.      */
  402.     public synchronized void removeVetoableChangeListener(VetoableChangeListener listener)
  403.     {
  404.         super.removeVetoableChangeListener(listener);
  405.         vetos.removeVetoableChangeListener(listener);
  406.     }
  407.  
  408.     /**
  409.      * Adds a listener for the Direction property changes.
  410.      * @param listener the listener to add.
  411.      * @see #removeDirectionListener
  412.      */
  413.     public synchronized void addDirectionListener(PropertyChangeListener listener)
  414.     {
  415.         changes.addPropertyChangeListener("direction", listener);
  416.     }
  417.  
  418.     /**
  419.      * Removes a listener for the Direction property changes.
  420.      * @param listener the listener to remove.
  421.      * @see #addDirectionListener
  422.      */
  423.     public synchronized void removeDirectionListener(PropertyChangeListener listener)
  424.     {
  425.         changes.removePropertyChangeListener("direction", listener);
  426.     }
  427.  
  428.     /**
  429.      * Adds a vetoable listener for the Direction property changes.
  430.      * @param listener the listener to add.
  431.      * @see #removeDirectionListener
  432.      */
  433.     public synchronized void addDirectionListener(VetoableChangeListener listener)
  434.     {
  435.         vetos.addVetoableChangeListener("direction", listener);
  436.     }
  437.  
  438.     /**
  439.      * Removes a vetoable listener for the Direction property changes.
  440.      * @param listener the listener to remove.
  441.      * @see #addDirectionListener
  442.      */
  443.     public synchronized void removeDirectionListener(VetoableChangeListener listener)
  444.     {
  445.         vetos.removeVetoableChangeListener("direction", listener);
  446.     }
  447.  
  448.     /**
  449.      * Adds a listener for the ArrowIndent property changes.
  450.      * @param listener the listener to add.
  451.      * @see #removeArrowIndentListener
  452.      */
  453.     public synchronized void addArrowIndentListener(PropertyChangeListener listener)
  454.     {
  455.         changes.addPropertyChangeListener("arrowIndent", listener);
  456.     }
  457.  
  458.     /**
  459.      * Removes a listener for the ArrowIndent property changes.
  460.      * @param listener the listener to remove.
  461.      * @see #addArrowIndentListener
  462.      */
  463.     public synchronized void removeArrowIndentListener(PropertyChangeListener listener)
  464.     {
  465.         changes.removePropertyChangeListener("arrowIndent", listener);
  466.     }
  467.  
  468.     /**
  469.      * Adds a vetoable listener for the ArrowIndent property changes.
  470.      * @param listener the listener to add.
  471.      * @see #removeArrowIndentListener
  472.      */
  473.     public synchronized void addArrowIndentListener(VetoableChangeListener listener)
  474.     {
  475.         vetos.addVetoableChangeListener("arrowIndent", listener);
  476.     }
  477.  
  478.     /**
  479.      * Removes a vetoable listener for the ArrowIndent property changes.
  480.      * @param listener the listener to remove.
  481.      * @see #addArrowIndentListener
  482.      */
  483.     public synchronized void removeArrowIndentListener(VetoableChangeListener listener)
  484.     {
  485.         vetos.removeVetoableChangeListener("arrowIndent", listener);
  486.     }
  487.  
  488.     /**
  489.      * This is the PropertyChangeEvent handling inner class for the constrained Direction property.
  490.      * Handles vetoing Directions that are not valid.
  491.      */
  492.     class SizeVeto implements java.beans.VetoableChangeListener, java.io.Serializable
  493.     {
  494.         /**
  495.          * This method gets called when an attempt to change the constrained Direction property is made.
  496.          * Ensures the given direction size is valid for this button.
  497.          *
  498.          * @param     e a <code>PropertyChangeEvent</code> object describing the
  499.          *             event source and the property that has changed.
  500.          * @exception PropertyVetoException if the recipient wishes the property
  501.          *              change to be rolled back.
  502.          */
  503.         public void vetoableChange(PropertyChangeEvent e) throws PropertyVetoException
  504.         {
  505.             int i = ((Integer)e.getNewValue()).intValue();
  506.             if (!isValidDirection(i))
  507.             {
  508.                 throw new PropertyVetoException(errors.getString("InvalidDirection") + i, e);
  509.             }
  510.         }
  511.     }
  512.  
  513.     /**
  514.      * This is the PropertyChangeEvent handling inner class for the constrained ArrowIndent property.
  515.      * Handles vetoing ArrowIndents that are not valid.
  516.      */
  517.     class IndntVeto implements java.beans.VetoableChangeListener, java.io.Serializable
  518.     {
  519.         /**
  520.          * This method gets called when an attempt to change the constrained ArrowIndent property is made.
  521.          * Ensures the given arrow indent size is valid for this button.
  522.          *
  523.          * @param     e a <code>PropertyChangeEvent</code> object describing the
  524.          *             event source and the property that has changed.
  525.          * @exception PropertyVetoException if the recipient wishes the property
  526.          *              change to be rolled back.
  527.          */
  528.         public void vetoableChange(PropertyChangeEvent e) throws PropertyVetoException
  529.         {
  530.             int i = ((Integer)e.getNewValue()).intValue();
  531.             if (!isValidArrowIndent(i))
  532.             {
  533.                 throw new PropertyVetoException(errors.getString("InvalidArrowIndent") + i, e);
  534.             }
  535.         }
  536.     }
  537.  
  538.  
  539.     /**
  540.      * Maintains the buttonImage size and draws the
  541.      * button in the buttonImage offscreen image.
  542.      * @see symantec.itools.awt.ButtonBase#updateButtonImage
  543.      */
  544.     protected void updateButtonImage()
  545.     {
  546.         super.updateButtonImage();
  547.         Graphics g        = buttonImage.getGraphics();
  548.         Dimension s        = size();;
  549.         int trueBevel    = bevel + 1;
  550.         int centerHorizontal;
  551.         int centerVertical;
  552.         int topSide;
  553.         int bottomSide;
  554.         int leftSide;
  555.         int rightSide;
  556.  
  557.         if(isEnabled())
  558.         {
  559.             g.setColor(arrowColor);
  560.         }
  561.         else
  562.         {
  563.             g.setColor(disabledArrowColor);
  564.         }
  565.  
  566.         centerHorizontal    = ((s.width - 1) / 2)                    + pressedAdjustment;
  567.         centerVertical        = ((s.height - 1) / 2)                    + pressedAdjustment;
  568.         topSide                = (top + trueBevel - 1)                    + pressedAdjustment  + indent;
  569.         bottomSide            = (s.height - 1 - bottom - trueBevel)    + pressedAdjustment  - indent;
  570.         leftSide            = (left + trueBevel - 1)                + pressedAdjustment  + indent;
  571.         rightSide            = (s.width - 1 - right - trueBevel)        + pressedAdjustment  - indent;
  572.  
  573.         if (symantec.itools.lang.OS.isMacintosh())
  574.         {
  575.             leftSide    += 1;
  576.             topSide        += 1;
  577.         }
  578.  
  579.         switch (direction)
  580.         {
  581.             case UP:
  582.             {
  583.                 fillTriangle(g, centerHorizontal, topSide, leftSide, bottomSide, rightSide, bottomSide, direction);
  584.                 break;
  585.             }
  586.             case DOWN:
  587.             {
  588.                 fillTriangle(g, centerHorizontal, bottomSide, leftSide, topSide, rightSide, topSide, direction);
  589.                 break;
  590.             }
  591.  
  592.             case LEFT:
  593.             {
  594.                 fillTriangle(g, leftSide, centerVertical, rightSide, bottomSide, rightSide, topSide, direction);
  595.                 break;
  596.             }
  597.  
  598.             case RIGHT:
  599.             {
  600.                 fillTriangle(g, rightSide, centerVertical, leftSide, bottomSide, leftSide, topSide, direction);
  601.                 break;
  602.             }
  603.         }
  604.         if (g != null)
  605.             g.dispose();
  606.     }
  607.  
  608.     /**
  609.      * Fills a triangle which has at least one side that is straight up and down or left and right.
  610.      * @param g the Graphics to use to draw with.
  611.      * @param tipX the horizontal coordinate of the point opposite a straight side.
  612.      * @param tipY the vertical coordinate of the point opposite a straight side.
  613.      * @param aX the horizontal coordinate of one of the two points defining the straight side.
  614.      * @param aY the vertical coordinate of one of the two points defining the straight side.
  615.      * @param bX the horizontal coordinate of one of the two points defining the straight side.
  616.      * @param bY the vertical coordinate of one of the two points defining the straight side.
  617.      * @param direction the direction of the straight line UP, DOWN, or LEFT, RIGHT.
  618.      *
  619.      * aX and bX should be the same for UP or Down.  aY and bY should be the same for LEFT or RIGHT.
  620.      * If not, then the a coordinates are used.
  621.      *
  622.      * @see #UP
  623.      * @see #DOWN
  624.      * @see #LEFT
  625.      * @see #RIGHT
  626.      */
  627.     protected void fillTriangle(Graphics g, int tipX, int tipY, int aX, int aY, int bX, int bY, int direction)
  628.     {
  629.         int dist, max, min;
  630.  
  631.         switch(direction)
  632.         {
  633.             case UP:
  634.             case DOWN:
  635.                 dist = Math.abs(aX - bX);
  636.                 max = Math.max(aX, bX);
  637.                 min = Math.min(aX, bX);
  638.                 for(int i = min; i <= max; ++i)
  639.                 {
  640.                     g.drawLine(tipX, tipY, i, aY);
  641.                 }
  642.                 break;
  643.             case RIGHT:
  644.             case LEFT:
  645.                 dist = Math.abs(aY - bY);
  646.                 max = Math.max(aY, bY);
  647.                 min = Math.min(aY, bY);
  648.                 for(int i = min; i <= max; ++i)
  649.                 {
  650.                     g.drawLine(tipX, tipY, aX, i);
  651.                 }
  652.                 break;
  653.         }
  654.     }
  655.  
  656.     /**
  657.      * Is the given bevel size valid for this button.
  658.      * @param i the given bevel size
  659.      * @return true if the given bevel size is acceptable, false if not.
  660.      */
  661.     protected boolean isValidBevelSize(int i)
  662.     {
  663.         Dimension s = size();
  664.  
  665.         int temp = i * 2 + 4;
  666.  
  667.         if (i < 0 || s.width < temp || s.height < temp)
  668.             return false;
  669.         else
  670.             return true;
  671.     }
  672.  
  673.     /**
  674.      * Is the given direction valid for this button.
  675.      * @param i the given bevel size
  676.      * @return true if the given direction is acceptable, false if not.
  677.      */
  678.     protected boolean isValidDirection(int i)
  679.     {
  680.         switch(i)
  681.         {
  682.             case LEFT:
  683.             case RIGHT:
  684.             case UP:
  685.             case DOWN:
  686.                 return true;
  687.             default:
  688.                 return false;
  689.         }
  690.     }
  691.  
  692.     /**
  693.      * Is the given arrow indent is valid for this button.
  694.      * @param i the given bevel size
  695.      * @return true if the given indent size is acceptable, false if not.
  696.      */
  697.     protected boolean isValidArrowIndent(int i)
  698.     {
  699.         Dimension s = size();
  700.  
  701.         int temp = (i * 2) + (bevel + 1) * 2 + 4;
  702.  
  703.         if(i < 0 || s.width < temp || s.height < temp)
  704.             return false;
  705.         else
  706.             return true;
  707.     }
  708.  
  709.     /**
  710.      * Called after addNotify to set the internally constrined properties to their
  711.      * temporary values to validate them now that the component has been added to the form.
  712.      * This is used to avoid code-gen order dependencies, since VC generates all property
  713.      * manipulating code before adding the component to its container.
  714.      * Subclasses should override this function for any internally constrained properties,
  715.      * and call the super version in the overridden version.
  716.      */
  717.     protected void verifyContstrainedPropertyValues()
  718.     {
  719.         super.verifyContstrainedPropertyValues();
  720.         try { setArrowIndent(tempIndent); } catch (PropertyVetoException exc) { /*Silently verify.*/ }
  721.     }
  722.  
  723.     /**
  724.      * The color of the arrow in the button.
  725.      */
  726.     protected Color    arrowColor            = null;
  727.     /**
  728.      * The color of the arrow when the button is disabled.
  729.      */
  730.     protected Color    disabledArrowColor    = null;
  731.     /**
  732.      * The direction the arrow points.
  733.      * One of: LEFT, UP, RIGHT, or DOWN.
  734.      * @see #LEFT
  735.      * @see #UP
  736.      * @see #RIGHT
  737.      * @see #DOWN
  738.      */
  739.     protected int        direction;
  740.     /**
  741.      * The number of pixels to shrink the arrow from the left side of the button.
  742.      */
  743.     protected int        left;
  744.     /**
  745.      * The number of pixels to shrink the arrow from the right side of the button.
  746.      */
  747.     protected int        right;
  748.     /**
  749.      * The number of pixels to shrink the arrow from the top side of the button.
  750.      */
  751.     protected int        top;
  752.     /**
  753.      * The number of pixels to shrink the arrow from the bottom side of the button.
  754.      */
  755.     protected int        bottom;
  756.     /**
  757.      * The margin around the arrow in pixels. 0 = arrow takes up entire button.
  758.      */
  759.     protected int        indent;
  760.     /**
  761.      * Internal use.
  762.      * Indent value stored until this component is added to a container.
  763.      * It is then used to set the real indent value.
  764.      * This avoids code-gen order dependencies.
  765.      */
  766.     protected int        tempIndent;
  767.     /**
  768.      * Error strings.
  769.      */
  770.     transient protected ResourceBundle errors;
  771.  
  772.     private SizeVeto    sizeVeto    = null;
  773.     private IndntVeto    indentVeto    = null;
  774.     private symantec.itools.beans.VetoableChangeSupport vetos = new symantec.itools.beans.VetoableChangeSupport(this);
  775.     private symantec.itools.beans.PropertyChangeSupport changes = new symantec.itools.beans.PropertyChangeSupport(this);
  776. }
  777.